package net.gyapp.lbc.app4locationonlygps;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.CoordinateConverter;
import com.baidu.mapapi.utils.DistanceUtil;
import com.fastaccess.permission.base.PermissionHelper;
import com.fastaccess.permission.base.callback.OnPermissionCallback;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity implements OnPermissionCallback {
    LocationManager locationManager;
    //
    //private boolean isGpsEnabled;
    //定位类型,分为网络和gps
    private String locateType;
    boolean isFirstLoc = true; // 是否首次定位
    long lastLocTime = -1;//前一次定位成功的时间
    private static final String TAG = MainActivity.class.getSimpleName();
    private static final String GPS_LOCATION_NAME = LocationManager.GPS_PROVIDER;
    private static final String NETWORK_LOCATION_NAME = LocationManager.NETWORK_PROVIDER;
    //权限请求码
    private static final int REQUEST_PRESSMION_CODE = 10000;
    //权限列表
    private final static String[] MULTI_PERMISSIONS = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION};
    //经纬度坐标集合
    List<LatLng> points = new ArrayList<>();
    //
    PermissionHelper mPermissionHelper;

    TextView textView;
    BaiduMap baiduMap;
    MapView mapView;
    Button startBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        startBtn = (Button) findViewById(R.id.startBtn);
        mapView = (MapView) findViewById(R.id.mapView);
        baiduMap = mapView.getMap();

        baiduMap.setMyLocationEnabled(true);

        //startBtn.setEnabled(false);
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (startBtn.getText().equals("开始记录")) {
                    startBtn.setText("结束记录");
                    points.clear();
                    startGetLocation();
                    baiduMap.clear();
                } else {
                    startBtn.setText("开始记录");
                    //绘制运动轨迹
                    drawWalkPath();
                    //
                    showWalkResult();
                }

            }
        });

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        //判断是否开启GPS定位功能
        //isGpsEnabled = locationManager.isProviderEnabled(GPS_LOCATION_NAME);

        //定位类型：GPS
        //locateType = NETWORK_LOCATION_NAME;

        //初始化PermissionHelper
        mPermissionHelper = PermissionHelper.getInstance(MainActivity.this);

        //getLocation();

    }

    protected void onDestroy(){
        super.onDestroy();
        stopLocation();
    }
    /**
     * 在地图上绘制行走路径
     */
    private void drawWalkPath() {
        if (points.size() < 2) {
            Toast.makeText(this, "路径太少", Toast.LENGTH_SHORT).show();
            return;
        }
        // 构造折线点坐标
//        List<LatLng> points = new ArrayList<LatLng>();
//        points.add(new LatLng(30.555,104.063));
//        points.add(new LatLng(30.565,104.063));
//        points.add(new LatLng(30.555,104.073));
//        points.add(new LatLng(30.565,104.083));
//        points.add(new LatLng(30.555,104.093));


//构建分段颜色索引数组
        //List<Integer> colors = new ArrayList<>();
        int randomColor = Color.argb(255, (int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));
        // colors.add(Integer.valueOf(randomColor));
//        colors.add(Integer.valueOf(Color.BLUE));
//        colors.add(Integer.valueOf(Color.RED));
//        colors.add(Integer.valueOf(Color.YELLOW));
//        colors.add(Integer.valueOf(Color.GREEN));

        OverlayOptions ooPolyline = new PolylineOptions().width(10)
                .points(points).color(randomColor);
        //添加在地图中
        Polyline mPolyline = (Polyline) baiduMap.addOverlay(ooPolyline);


    }

    /**
     * 提示行走结果
     */
    private void showWalkResult() {

        AlertDialog alertDialog = new AlertDialog.Builder(this)
                .setMessage("行走路程: " + getDistance())
                .setTitle("结束行程")
                .setNegativeButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setPositiveButton("继续行程", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        points.clear();
                        startBtn.setText("结束记录");
                    }
                })
                .create();

        alertDialog.show();

    }

    /**
     * 获取行走路程
     * @return
     */
    private String getDistance() {
        float distance = 0;
        if (points == null || points.size() == 0) {
            return "0m";
        }
        for (int i = 0; i < points.size() - 1; i++) {
            LatLng firstLatLng = points.get(i);
            LatLng secondLatLng = points.get(i + 1);
//            LatLng firstLatLng = new LatLng(firstpoint.getLatitude(),
//                    firstpoint.getLongitude());
//            LatLng secondLatLng = new LatLng(secondpoint.getLatitude(),
//                    secondpoint.getLongitude());
            double betweenDis = //.calculateLineDistance(firstLatLng,
                    //secondLatLng);
                    DistanceUtil.getDistance(firstLatLng, secondLatLng);

            distance = (float) (distance + betweenDis);
        }
        if (distance > 1000)
            return distance / 1000 + "km";
        return distance + "m";
    }

    /**
     * 开始定位
     */
    private void startGetLocation() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
                (MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            mPermissionHelper.request(MULTI_PERMISSIONS);
            return;
        }

        locateType = getProvider();

        Location location = locationManager.getLastKnownLocation(locateType); // 通过GPS获取位置
        if (location != null) {
            refreshLocation(location);
            updateUI(location);
        }


        // 设置监听*器，自动更新的最小时间为间隔N秒(1秒为1*1000，这样写主要为了方便)或最小位移变化超过N米
        locationManager.requestLocationUpdates(locateType, 500, 1,
                locationListener);
    }

    private void stopLocation() {
        if (locationManager != null) {
            if (locationListener != null)
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
                        (MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED) {
                    mPermissionHelper.request(MULTI_PERMISSIONS);
                    return;
                }
            locationManager.removeUpdates(locationListener);

            locationManager = null;
        }
    }
    // 获取Location Provider
    private String getProvider() {
        // 构建位置查询条件
        Criteria criteria = new Criteria();
        // 查询精度：高
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        // 是否查询海拨：否
        criteria.setAltitudeRequired(false);
        // 是否查询方位角 : 否
        criteria.setBearingRequired(false);
        // 是否允许付费：是
        criteria.setCostAllowed(true);
        // 电量要求：低
        //criteria.setPowerRequirement(Criteria.POWER_LOW);
        // 返回最合适的符合条件的provider，第2个参数为true说明 , 如果只有一个provider是有效的,则返回当前provider
        return locationManager.getBestProvider(criteria, true);
    }
    /**
     * 方法描述：在View上更新位置信息的显示
     *
     * @param location
     */
    private void updateUI(Location location) {
        double longitude = location.getLongitude();
        double latitude = location.getLatitude();
        textView.setText("当前经度：" + longitude + "\n当前纬度：" + latitude + " \n精度：" + location.getAccuracy() +
        "   方向：" + location.getBearing()
        );
    }

    private void refreshLocation(Location location){
        LatLng sourceLatLng = new LatLng(location.getLatitude(),location.getLongitude());
        // 将GPS设备采集的原始GPS坐标转换成百度坐标
        CoordinateConverter converter  = new CoordinateConverter();
        converter.from(CoordinateConverter.CoordType.GPS);
        // sourceLatLng待转换坐标
        converter.coord(sourceLatLng);
        LatLng desLatLng = converter.convert();

        points.add(desLatLng);
        long now = System.currentTimeMillis();
        //if (now - lastLocTime > 3 * 1000) {
            //location.getAccuracy()
            MyLocationData locData = new MyLocationData.Builder()
                    //.accuracy(location.getAccuracy())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    //.direction(location.getBearing())
                    .latitude(desLatLng.latitude)
                    .longitude(desLatLng.longitude).build();
            baiduMap.setMyLocationData(locData);

        MapStatus.Builder builder = new MapStatus.Builder();
        LatLng ll = new LatLng(desLatLng.latitude,
                desLatLng.longitude);
        if (isFirstLoc) {
            isFirstLoc = false;
            //baiduMap.
            //float zoomLevel = baiduMap.getMapStatus().zoom;
            builder.target(ll).zoom(18.f);
            baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
        baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        // }
    }

    private LocationListener locationListener = new LocationListener() {
        /**
         * 位置信息变化时触发:当坐标改变时触发此函数，如果Provider传进相同的坐标，它就不会被触发
         * @param location
         */
        @Override
        public void onLocationChanged(Location location) {
            Toast.makeText(MainActivity.this, "onLocationChanged函数被触发！", Toast.LENGTH_SHORT).show();

            updateUI(location);
            
            Log.i(TAG, "时间：" + location.getTime());
            Log.i(TAG, "经度：" + location.getLongitude());
            Log.i(TAG, "纬度：" + location.getLatitude());
            Log.i(TAG, "海拔：" + location.getAltitude());

            refreshLocation(location);

        }

        /**
         * GPS状态变化时触发:Provider被disable时触发此函数，比如GPS被关闭
         * @param provider
         * @param status
         * @param extras
         */
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                //GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    startBtn.setEnabled(true);
                    toastInfo(provider,"可见");

                    //Toast.makeText(MainActivity.this, "onStatusChanged：当前GPS状态为可见状态", Toast.LENGTH_SHORT).show();
                    break;
                //GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    startBtn.setEnabled(false);
                    toastInfo(provider,"服务区外");

                    //Toast.makeText(MainActivity.this, "onStatusChanged:当前GPS状态为服务区外状态", Toast.LENGTH_SHORT).show();
                    break;
                //GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    startBtn.setEnabled(false);
                    toastInfo(provider,"暂停服务");

                    //Toast.makeText(MainActivity.this, "onStatusChanged:当前GPS状态为暂停服务状态", Toast.LENGTH_SHORT).show();
                    break;
            }
        }

        /**
         * 方法描述：GPS开启时触发
         * @param provider
         */
        @Override
        public void onProviderEnabled(String provider) {
            toastInfo(provider,"打开");

            startGetLocation();
        }

        /**
         * 方法描述： GPS禁用时触发
         * @param provider
         */
        @Override
        public void onProviderDisabled(String provider) {
            toastInfo(provider,"关闭");
        }
    };

    private void toastInfo(String provider,String info){
        if (provider.equals(NETWORK_LOCATION_NAME)){
            Toast.makeText(MainActivity.this, "移动网络" + info, Toast.LENGTH_SHORT).show();

        }else if (provider.equals(GPS_LOCATION_NAME)){
            Toast.makeText(MainActivity.this, "gps" + info, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        mPermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        mPermissionHelper.onActivityForResult(requestCode);
    }

    @Override
    public void onPermissionGranted(@NonNull String[] permissionName) {
        startGetLocation();
        Log.i("onPermissionGranted", "Permission(s) " + Arrays.toString(permissionName) + " Granted");
    }

    @Override
    public void onPermissionDeclined(@NonNull String[] permissionName) {

    }

    @Override
    public void onPermissionPreGranted(@NonNull String permissionsName) {

    }

    @Override
    public void onPermissionNeedExplanation(@NonNull String permissionName) {

    }

    @Override
    public void onPermissionReallyDeclined(@NonNull String permissionName) {

    }

    @Override
    public void onNoPermissionNeeded() {

    }

}
